﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
using System.Text;
using StandardDAC.Base;
using System.Text.RegularExpressions;

namespace StandardDAC.OleDb {
    internal class OleDBTypeAdapter : IDBTypeAdapter {
        #region IDBTypeAdapter Members

        public DbCommand NewCommand(string commandText, DbConnection connection, ConnOrTranInfo conn) {
            OleDbCommand cmd = new OleDbCommand(commandText, (OleDbConnection)connection);
            if (conn is TranInfo)
                cmd.Transaction = (OleDbTransaction)((TranInfo)conn).Transaction;
            return cmd;
        }

        public DbConnection NewConnection(ConnOrTranInfo conn) {
            if (conn is ConnInfo) {
                OleDbConnection c = new OleDbConnection(((ConnInfo)conn).ConnectionString);
                c.Open();
                return c;
            } else
                return ((TranInfo)conn).Transaction.Connection;
        }

        public DbDataAdapter NewAdapter(DbCommand command) {
            return new OleDbDataAdapter((OleDbCommand)command);
        }

        public DbParameter AddNewParameter(string name, object dbType, DbCommand command) {
            return ((OleDbCommand)command).Parameters.Add(name, (OleDbType)dbType);
        }
        public void SortParametersIfNeeded(Dictionary<string, KeyValuePair<int, DBColumn>> parametersToSort, DbCommand cmd) {
            List<OleColumn> list = new List<OleColumn>(parametersToSort.Count);
            foreach (KeyValuePair<int, DBColumn> column in parametersToSort.Values) {
                list.Add((OleColumn)column.Value);
            }
            list.Sort();
            OleDbParameter[] ary = new OleDbParameter[list.Count];
            cmd.Parameters.CopyTo(ary, 0);
            cmd.Parameters.Clear();
            foreach (OleColumn column in list) {
                cmd.Parameters.Add(ary[parametersToSort[column.Name].Key]);
            }            
        }
        public DbParameter AddNewNullParameter(string name, DbCommand command) {
            return ((OleDbCommand)command).Parameters.AddWithValue(name, DBNull.Value);
        }

        public DbParameter AddExistingParameter(DbParameter param, DbCommand command) {
            return ((OleDbCommand)command).Parameters.Add((OleDbParameter)param);
        }

        public string ConvertNameToParam(string columnName) {
            return "@" + columnName;
        }
        public void PreExecute(DbCommand command) {
            if (command.CommandType == CommandType.StoredProcedure && !command.CommandText.ToLower().StartsWith("call ")) {
                command.CommandText = "call " + command.CommandText + "(" + getParam(command.Parameters.Count) + ")";
            }

            command.CommandText = fix(command.CommandText);
        }

        public string fix(string sql) {
            Regex r = new Regex("[\\r\\n]+");
            return r.Replace(sql, " ");
        }
        private string getParam(int numberParams) {
            string[] ary = new string[numberParams];
            for (int i = 0; i < numberParams; i++) {
                ary[i] = "?";
            }
            return String.Join(",", ary);
        }
        /// <summary>
        /// Not needed. Does nothing
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="type"></param>
        public void AddOutputCursorIfNeeded(DbCommand cmd, Type type) {
        }
        #endregion
    }
}
